package com.tianxiabuyi.utils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;

/**
 * 网络请求工具类
 * Created by yang on 2015/2/7.
 */
public final class HttpUtil {

    private HttpUtil() {
    }

    /**
     * 加密JSON发送，并返回服务端解密后的数据
     * @param url 资源地址
     * @param param 请求参数
     * @return 服务端解密后的数据
     */
    public static String encryptPost(String url, Map<String, String> param) {
        HashMap<String, String> map = new HashMap<String, String>();
        map.put("json", Crypt.encryptStr(JSONUtil.toJson(param)));
        String retVal = post(url, map);
        return Crypt.decryptStr(retVal);
    }

    /**
     * 向指定URL发送soap请求
     * @param url 发送请求的URL
     * @param params 请求参数,xml内容
     */
    public static String soap(String url, String params) throws Exception{
        return soap(url, params, StringUtil.UTF8);
    }

    /**
     * 向指定URL发送soap请求
     * @param url 发送请求的URL
     * @param params 请求参数,xml内容
     * @return encoding 编码
     */
    public static String soap(String url, String params, String encoding)
            throws Exception {
        CloseableHttpClient client = null;
        HttpPost post = new HttpPost(url);
        try {
            client  = HttpClientBuilder.create().build();
            StringEntity entity = new StringEntity(params,encoding);
            post.setEntity(entity);
            post.setHeader("accept", "*/*");
            post.setHeader("connection", "Keep-Alive");
            post.setHeader("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
            post.setHeader("Content-Type", "text/xml;charset="
                    + encoding);
            HttpResponse response = client.execute(post);
            if (response.getStatusLine().getStatusCode() == 200) {
                return streamToString(response.getEntity().getContent(), encoding);
            }
        } catch (Exception e) {
            System.out.println("soap请求出现异常！" + e);
            e.printStackTrace();
        } finally {
            if (post != null) {
                post.releaseConnection();
            }
            if (client != null) {
                try {
                    client.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return "";
    }

    /**
     * 获取请求指定地址后的sessionId
     * @param url 资源地址
     * @return sessionId
     */
    public static String sessionId(String url) {
        CloseableHttpClient client = null;
        HttpGet httpGet = new HttpGet(url);
        try {
            client = HttpClientBuilder.create().build();
            HttpResponse response = client.execute(httpGet);
            if (response.getStatusLine().getStatusCode() == 200) {
                Header[] headers = response.getAllHeaders();
                for (int i = 0; i < headers.length; i++) {
                    Header header = headers[i];
                    String name = header.getName();
                    if ("Set-Cookie".equals(name)) {
                        return header.getValue();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (httpGet != null) {
                httpGet.releaseConnection();
            }
            if (client != null) {
                try {
                    client.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return "";
    }

    /*
     * 发送get请求(不带参数，使用默认编码)
     */
    public static String get(String url) {
        return get(url, null, StringUtil.UTF8);
    }

    /*
     * 发送get请求
     */
    public static String get(String url, Map<String, String> params) {
        return get(url, params, StringUtil.UTF8);
    }

    /*
     * 发送get请求
     */
    public static String get(String url, String encode) {
        return get(url, null, encode);
    }

    /*
     * 发送get请求 params 请求参数 encode 编码
     */
    public static String get(String url, Map<String, String> params,
                             String encode) {
        if (params != null && !params.isEmpty()) {
            url += "?";
            for (Map.Entry<String, String> entry : params.entrySet()) {
                url += "&" + entry.getKey() + "=" + entry.getValue();
            }
        }
        url = url.replaceFirst("\\?&", "\\?");

        CloseableHttpClient client = null;
        HttpGet httpGet = new HttpGet(url);
        try {
            client = HttpClientBuilder.create().build();
            HttpResponse response = client.execute(httpGet);
            if (response.getStatusLine().getStatusCode() == 200) {
                return streamToString(response.getEntity().getContent(), encode);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (httpGet != null) {
                httpGet.releaseConnection();
            }
            if (client != null) {
                try {
                    client.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return "";
    }

    public static String post(String url) {
        return post(url, null, StringUtil.UTF8, null);
    }

    public static String post(String url, Map<String, String> params) {
        return post(url, params, StringUtil.UTF8, null);
    }

    public static String post(String url, String encode) {
        return post(url, null, encode, null);
    }

    public static String post(String url, Map<String, String> params,
                              String cookie) {
        return post(url, params, StringUtil.UTF8, cookie);
    }

    /*
     * 发送post请求 params 请求参数 encode 编码
     */
    public static String post(String url, Map<String, String> params,
                              String encode, String cookie) {
        List<NameValuePair> list = new ArrayList<NameValuePair>();
        if (params != null && !params.isEmpty()) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                list.add(new BasicNameValuePair(key, value));
            }
        }

        CloseableHttpClient client = null;
        HttpPost post = new HttpPost(url);
        try {
            client = HttpClientBuilder.create().build();
            if (cookie != null) {
                post.addHeader("Cookie", cookie);
            }
            UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, encode);
            post.setEntity(entity);
            HttpResponse response = client.execute(post);
            if (response.getStatusLine().getStatusCode() == 200) {
                return streamToString(response.getEntity().getContent(), encode);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (post != null) {
                post.releaseConnection();
            }
            if (client != null) {
                try {
                    client.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return "";
    }

    // 输入流转字符串
    private static String streamToString(InputStream inputStream, String encode) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        byte[] data = new byte[1024];
        int len = 0;
        String result = "";
        if (inputStream != null) {
            try {
                while ((len = inputStream.read(data)) != -1) {
                    outputStream.write(data, 0, len);
                }
                result = new String(outputStream.toByteArray(), encode);

                outputStream.close();
                inputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return result;
    }
}